package com.heyige.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heyige.dto.PromptTemplateDto;
import com.heyige.entity.PromptTemplate;
import com.heyige.exception.BusinessException;
import com.heyige.exception.ErrorCode;
import com.heyige.mapper.PromptTemplateMapper;
import com.heyige.service.PromptTemplateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class PromptTemplateServiceImpl extends ServiceImpl<PromptTemplateMapper, PromptTemplate> implements PromptTemplateService {

    private final PromptTemplateMapper promptTemplateMapper;

    /**
     * 获取提示词模板列表
     *
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplates(Page<PromptTemplate> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getIsActive, true)
                .orderByAsc(PromptTemplate::getSortOrder);

        Page<PromptTemplate> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 根据类型获取提示词模板列表
     *
     * @param type 类型
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplatesByType(PromptTemplate.TemplateType type, Page<PromptTemplate> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getType, type.toString())
                .eq(PromptTemplate::getIsActive, true)
                .orderByAsc(PromptTemplate::getSortOrder);

        Page<PromptTemplate> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 根据分类获取提示词模板列表
     *
     * @param category 分类
     * @param page     分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplatesByCategory(String category, Page<PromptTemplate> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getCategory, category)
                .eq(PromptTemplate::getIsActive, true)
                .orderByAsc(PromptTemplate::getSortOrder);

        Page<PromptTemplate> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 根据标签搜索提示词模板列表
     *
     * @param tags 标签
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getPromptTemplatesByTags(String tags, Page<PromptTemplate> page) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(PromptTemplate::getTags, tags)
                .eq(PromptTemplate::getIsActive, true)
                .orderByAsc(PromptTemplate::getSortOrder);

        Page<PromptTemplate> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        Page<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 获取用户的提示词模板列表
     *
     * @param userId 用户ID
     * @param page   分页参数
     * @return 提示词模板列表
     */
    public IPage<PromptTemplateDto.TemplateResponse> getUserPromptTemplates(Long userId, Page<PromptTemplate> page) {
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getUserId, userId)
                .eq(PromptTemplate::getIsActive, true)
                .orderByDesc(PromptTemplate::getCreatedAt);
        IPage<PromptTemplate> templates = promptTemplateMapper.selectPage(page, queryWrapper);
        // 转换结果
        IPage<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 获取公共提示词模板列表
     *
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public IPage<PromptTemplateDto.TemplateResponse> getPublicPromptTemplates(Page<PromptTemplate> page) {
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getIsPublic, true)
                .eq(PromptTemplate::getIsActive, true)
                .orderByAsc(PromptTemplate::getSortOrder);

        IPage<PromptTemplate> templates = promptTemplateMapper.selectPage(page, queryWrapper);

        // 转换结果
        IPage<PromptTemplateDto.TemplateResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(templates.getRecords().stream().map(this::buildTemplateResponse).collect(Collectors.toList()));
        responsePage.setTotal(templates.getTotal());
        return responsePage;
    }

    /**
     * 获取提示词模板详情
     *
     * @param id 提示词模板ID
     * @return 提示词模板详情
     */
    public PromptTemplateDto.TemplateResponse getPromptTemplate(Long id) {
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getId, id)
                .eq(PromptTemplate::getIsActive, true);

        PromptTemplate template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 增加使用次数
        LambdaUpdateWrapper<PromptTemplate> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PromptTemplate::getId, id).setSql("usage_count = usage_count + 1");
        promptTemplateMapper.update(null, updateWrapper);

        return buildTemplateResponse(template);
    }

    /**
     * 添加提示词模板
     *
     * @param userId  用户ID
     * @param request 添加请求
     * @return 提示词模板详情
     */
    @Transactional
    public PromptTemplateDto.TemplateResponse addPromptTemplate(Long userId, PromptTemplateDto.AddRequest request) {
        PromptTemplate template = new PromptTemplate();
        template.setTitle(request.getTitle());
        template.setDescription(request.getDescription());
        template.setCategory(request.getCategory());
        template.setType(request.getType().toString());
        template.setContent(request.getContent());
        template.setVariables(request.getVariables());
        template.setTags(request.getTags());
        template.setIsPublic(request.getIsPublic());
        template.setUserId(userId);
        template.setSortOrder(request.getSortOrder());

        promptTemplateMapper.insert(template);

        log.info("用户 {} 添加提示词模板: {}", userId, template.getTitle());

        return buildTemplateResponse(template);
    }

    /**
     * 更新提示词模板
     *
     * @param id      提示词模板ID
     * @param userId  用户ID
     * @param request 更新请求
     * @return 提示词模板详情
     */
    @Transactional
    public PromptTemplateDto.TemplateResponse updatePromptTemplate(Long id, Long userId, PromptTemplateDto.UpdateRequest request) {
        // 检查提示词模板是否存在
        PromptTemplate template = promptTemplateMapper.selectOne(new LambdaQueryWrapper<PromptTemplate>().eq(PromptTemplate::getId, id).eq(PromptTemplate::getIsActive, true));
        if (null == template) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 检查权限
        if (!template.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.FORBIDDEN, "无权限修改此提示词模板");
        }

        // 更新提示词模板
        if (StringUtils.hasText(request.getTitle())) {
            template.setTitle(request.getTitle());
        }
        if (StringUtils.hasText(request.getDescription())) {
            template.setDescription(request.getDescription());
        }
        if (StringUtils.hasText(request.getCategory())) {
            template.setCategory(request.getCategory());
        }
        if (request.getType() != null) {
            template.setType(request.getType().toString());
        }
        if (StringUtils.hasText(request.getContent())) {
            template.setContent(request.getContent());
        }
        if (StringUtils.hasText(request.getVariables())) {
            template.setVariables(request.getVariables());
        }
        if (StringUtils.hasText(request.getTags())) {
            template.setTags(request.getTags());
        }
        if (request.getIsPublic() != null) {
            template.setIsPublic(request.getIsPublic());
        }
        if (request.getSortOrder() != null) {
            template.setSortOrder(request.getSortOrder());
        }

        promptTemplateMapper.updateById(template);

        log.info("用户 {} 更新提示词模板: {}", userId, template.getTitle());

        return buildTemplateResponse(template);
    }

    /**
     * 删除提示词模板
     *
     * @param id     提示词模板ID
     * @param userId 用户ID
     */
    @Transactional
    public void deletePromptTemplate(Long id, Long userId) {
        // 检查提示词模板是否存在
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getId, id)
                .eq(PromptTemplate::getIsActive, true);

        PromptTemplate template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 检查权限
        if (!template.getUserId().equals(userId)) {
            throw new BusinessException(ErrorCode.FORBIDDEN, "无权限删除此提示词模板");
        }

        // 软删除提示词模板
        template.setIsActive(false);
        promptTemplateMapper.updateById(template);

        log.info("用户 {} 删除提示词模板: {}", userId, template.getTitle());
    }

    /**
     * 复制提示词模板
     *
     * @param id     提示词模板ID
     * @param userId 用户ID
     * @return 提示词模板详情
     */
    @Transactional
    public PromptTemplateDto.TemplateResponse copyPromptTemplate(Long id, Long userId) {
        // 检查提示词模板是否存在
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getId, id)
                .eq(PromptTemplate::getIsActive, true);

        PromptTemplate template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 创建新的提示词模板
        PromptTemplate newTemplate = new PromptTemplate();
        newTemplate.setTitle(template.getTitle() + " - 副本");
        newTemplate.setDescription(template.getDescription());
        newTemplate.setCategory(template.getCategory());
        newTemplate.setType(template.getType());
        newTemplate.setContent(template.getContent());
        newTemplate.setVariables(template.getVariables());
        newTemplate.setTags(template.getTags());
        newTemplate.setIsPublic(false); // 复制的模板默认为私有
        newTemplate.setUserId(userId);
        newTemplate.setSortOrder(template.getSortOrder());

        promptTemplateMapper.insert(newTemplate);

        log.info("用户 {} 复制提示词模板: {}", userId, template.getTitle());

        return buildTemplateResponse(newTemplate);
    }

    /**
     * 处理提示词模板
     *
     * @param id        提示词模板ID
     * @param variables 变量
     * @return 处理后的提示词
     */
    public PromptTemplateDto.ProcessResult processPromptTemplate(Long id, java.util.Map<String, String> variables) {
        // 检查提示词模板是否存在
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getId, id)
                .eq(PromptTemplate::getIsActive, true);

        PromptTemplate template = promptTemplateMapper.selectOne(queryWrapper);
        if (template == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND, "提示词模板不存在");
        }

        // 增加使用次数
        LambdaUpdateWrapper<PromptTemplate> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PromptTemplate::getId, id)
                .setSql("usage_count = usage_count + 1");
        promptTemplateMapper.update(null, updateWrapper);

        // 处理提示词
        String processedContent = template.getContent();
        List<PromptTemplateDto.VariableInfo> variableInfos = new ArrayList<>();

        // 解析变量
        if (StringUtils.hasText(template.getVariables())) {
            String[] variableArray = template.getVariables().split(",");
            for (String variable : variableArray) {
                variable = variable.trim();
                if (StringUtils.hasText(variable)) {
                    PromptTemplateDto.VariableInfo variableInfo = new PromptTemplateDto.VariableInfo();
                    variableInfo.setName(variable);

                    // 检查变量是否在模板中
                    String placeholder = "{" + variable + "}";
                    if (processedContent.contains(placeholder)) {
                        // 替换变量
                        String value = variables != null ? variables.get(variable) : "";
                        if (value == null) {
                            value = "";
                        }
                        processedContent = processedContent.replace(placeholder, value);

                        variableInfo.setFound(true);
                        variableInfo.setReplaced(true);
                    } else {
                        variableInfo.setFound(false);
                        variableInfo.setReplaced(false);
                    }

                    variableInfos.add(variableInfo);
                }
            }
        }

        // 构建结果
        PromptTemplateDto.ProcessResult result = new PromptTemplateDto.ProcessResult();
        result.setTemplateId(template.getId());
        result.setTemplateTitle(template.getTitle());
        result.setOriginalContent(template.getContent());
        result.setProcessedContent(processedContent);
        result.setVariables(variableInfos);

        return result;
    }

    /**
     * 获取热门提示词模板
     *
     * @param limit 限制数量
     * @return 提示词模板列表
     */
    public List<PromptTemplateDto.TemplateResponse> getHotPromptTemplates(Integer limit) {
        // 使用MyBatis-Plus的LambdaQueryWrapper构建查询条件
        LambdaQueryWrapper<PromptTemplate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PromptTemplate::getIsPublic, true)
                .eq(PromptTemplate::getIsActive, true)
                .orderByDesc(PromptTemplate::getUsageCount);

        List<PromptTemplate> templates = promptTemplateMapper.selectList(queryWrapper);

        if (limit != null && limit > 0) {
            templates = templates.subList(0, Math.min(limit, templates.size()));
        }

        List<PromptTemplateDto.TemplateResponse> responses = new ArrayList<>();
        for (PromptTemplate template : templates) {
            responses.add(buildTemplateResponse(template));
        }

        return responses;
    }

    /**
     * 获取小红书文案模板
     *
     * @param page 分页参数
     * @return 提示词模板列表
     */
    public Page<PromptTemplateDto.TemplateResponse> getRedBookTemplates(Page<PromptTemplate> page) {
        return getPromptTemplatesByType(PromptTemplate.TemplateType.RED_BOOK, page);
    }

    /**
     * 构建模板响应
     *
     * @param template 模板实体
     * @return 模板响应
     */
    private PromptTemplateDto.TemplateResponse buildTemplateResponse(PromptTemplate template) {
        PromptTemplateDto.TemplateResponse response = new PromptTemplateDto.TemplateResponse();
        response.setId(template.getId());
        response.setTitle(template.getTitle());
        response.setDescription(template.getDescription());
        response.setCategory(template.getCategory());
        response.setType(PromptTemplate.TemplateType.valueOf(template.getType()));
        response.setContent(template.getContent());
        response.setVariables(template.getVariables());
        response.setTags(template.getTags());
        response.setIsPublic(template.getIsPublic());
        response.setUserId(template.getUserId());
        response.setUsageCount(template.getUsageCount());
        response.setSortOrder(template.getSortOrder());
        response.setCreatedAt(template.getCreatedAt());
        response.setUpdatedAt(template.getUpdatedAt());

        return response;
    }
}